package com.asuka.service.impl;

import com.asuka.dto.TurnoverStatisticsDTO;
import com.asuka.entity.*;
import com.asuka.exception.BaseException;
import com.asuka.mapper.ReportMapper;
import com.asuka.service.ReportService;
import com.asuka.service.WorkspaceService;
import com.asuka.vo.*;
import io.swagger.models.auth.In;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
public class ReportServiceImpl implements ReportService {

    @Autowired
    private ReportMapper reportMapper;

    @Autowired
    private WorkspaceService workspaceService;

    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        if(end.isBefore(begin)){
            throw new BaseException("查询时间错误");
        }

        List<LocalDate> localDateList = getEveryConsecutiveDay(begin,end);

        //按组查询
        List<OrderStatistics> list = reportMapper.turnoverStatistics(begin, end, Orders.COMPLETED);

        //把查询的结果放到hash里
        HashMap<LocalDate, BigDecimal> hash = new HashMap<>();
        for (OrderStatistics orderStatistics : list) {
            hash.put(orderStatistics.getOrderTime(),orderStatistics.getAmount());
        }


        List<BigDecimal> amountList = new ArrayList<>();
        for (LocalDate localDate : localDateList) {
            //如果hash里有的话返回对应值, 无 返回0
            BigDecimal value = hash.getOrDefault(localDate, BigDecimal.valueOf(0));
            amountList.add(value);
        }


        String time = StringUtils.join(localDateList, ',');
        String amount = StringUtils.join(amountList,',');
        return new TurnoverReportVO(time,amount);
    }


    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        if(begin.isAfter(end)){
            throw new BaseException();
        }


        List<LocalDate> dataList = getEveryConsecutiveDay(begin,end);

        //查询数据库
        List<NewUser> newUsers = reportMapper.newUser(begin,end);
        //查询 begin 日期之前的用户数
        Integer sum = reportMapper.selectSumByData(begin);


        //将newusers加到hash表里
        HashMap<LocalDate,Integer> newUsersHash = new HashMap<>();
        for (NewUser newUser : newUsers) {
            newUsersHash.put(newUser.getCreateTime(),newUser.getNumber());
        }


        List<Integer> newUserList = new ArrayList<>();
        List<Integer> totalUserList = new ArrayList<>();


        //循环要查询的日期,添加新增人数和总人数
        for (LocalDate localDate : dataList) {

            //获取每一天新的人数
            Integer newNumber = newUsersHash.getOrDefault(localDate, 0);
            newUserList.add(newNumber);

            sum += newNumber;
            totalUserList.add(Integer.valueOf(sum));

        }


        return UserReportVO.builder()
                .dateList(StringUtils.join(dataList,','))
                .newUserList(StringUtils.join(newUserList,','))
                .totalUserList(StringUtils.join(totalUserList,','))
                .build();
    }


    @Override
    public OrderReportVO orderStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = getEveryConsecutiveDay(begin, end);

        // 订单总数 和 有效订单
        Integer orderSum = 0;
        Integer effecOrder = 0;

        List<OrderReport> effecOrderList = reportMapper.selectByTimeAndStatus(begin,end,Orders.COMPLETED);

        //将有效订单加入到hash
        HashMap<LocalDate,Integer> effecOrderHash = new HashMap<>();
        for (OrderReport orderReport : effecOrderList) {
            effecOrderHash.put(orderReport.getOrderTime(),orderReport.getCount());
        }


        List<OrderReport> allOtherList = reportMapper.selectByTimeAndStatus(begin,end,null);
        //将其他状态的订单加入到hash里
        HashMap<LocalDate,Integer> allHash = new HashMap<>();
        for (OrderReport orderReport : allOtherList) {
            allHash.put(orderReport.getOrderTime(),orderReport.getCount());
        }

        //所有订单
        List<Integer> orderCountList = new ArrayList<>();
        //有效订单
        List<Integer> validOrderCountList = new ArrayList<>();

        //遍历每一天
        for (LocalDate localDate : dateList) {
            Integer allother = allHash.getOrDefault(localDate, 0);
            Integer effec = effecOrderHash.getOrDefault(localDate, 0);


            orderCountList.add(allother);
            validOrderCountList.add(effec);

            orderSum += allother;
            effecOrder += effec;
        }

        Double number = orderSum == 0 ? 0.0 : effecOrder.doubleValue()/orderSum.doubleValue();;


        return OrderReportVO.builder()
                .dateList(StringUtils.join(dateList,","))
                .orderCompletionRate(number)
                .orderCountList(StringUtils.join(orderCountList,","))
                .totalOrderCount(orderSum)
                .validOrderCount(effecOrder)
                .validOrderCountList(StringUtils.join(validOrderCountList,","))
                .build();
    }


    @Override
    public TopVo topStatistics(LocalDate begin, LocalDate end) {

        List<Top> tops = reportMapper.selectTop(begin,end);

        tops.sort(Comparator.comparingLong(Top::getSum).reversed());

        List<String> nameList = new ArrayList<>();
        List<Long> numList = new ArrayList<>();

        for (Top top : tops) {
            nameList.add(top.getName());
            numList.add(top.getSum());
        }



        return TopVo.builder()
                .nameList(StringUtils.join(nameList,","))
                .numberList(StringUtils.join(numList,","))
                .build();
    }


    @Override
    public void exportExcel(HttpServletResponse response) {
        LocalDate begin = LocalDate.now().minusDays(30);
        LocalDate end = LocalDate.now().minusDays(1);

        //获取数据
        BusinessVO bvo = workspaceService.businessData();
        OrderReportVO orvo = orderStatistics(begin, end);

        InputStream is = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表.xlsx");

        try {
            XSSFWorkbook excel = new XSSFWorkbook(is);

            XSSFSheet sheet = excel.getSheetAt(0);

            //设置时间
            sheet.getRow(1).getCell(1).setCellValue("时间: "+begin+" - "+end);
            //设置营业额
            sheet.getRow(3).getCell(2).setCellValue(bvo.getTurnover().toString());
            //订单完成率
            sheet.getRow(3).getCell(4).setCellValue(bvo.getOrderCompletionRate());
            //新用户
            sheet.getRow(3).getCell(6).setCellValue(bvo.getNewUsers());
            //有效订单
            sheet.getRow(4).getCell(2).setCellValue(bvo.getValidOrderCount());
            //平均客单价
            sheet.getRow(4).getCell(4).setCellValue(bvo.getUnitPrice().toString());


            ServletOutputStream sos = response.getOutputStream();
            excel.write(sos);

            sos.close();
            excel.close();

        } catch (IOException e) {
            throw new RuntimeException(e);
        }



    }


    List<LocalDate> getEveryConsecutiveDay(LocalDate begin, LocalDate end){
        LocalDate temp = begin;
        List<LocalDate> dataList = new ArrayList<>();

        while (!temp.equals(end)){
            dataList.add(temp);
            temp = temp.plusDays(1);
        }

        return dataList;
    }



}
